package cn.juque.lucenecandy.core.datasync.tcc;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import cn.juque.lucenecandy.bo.IndexBO;
import cn.juque.lucenecandy.core.base.BaseEntity;
import cn.juque.lucenecandy.core.constants.StrConstant;
import cn.juque.lucenecandy.helper.DocumentHelper;
import cn.juque.lucenecandy.helper.LuceneHelper;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.TermQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>CandyCommitService</li>
 * </ul>
 * @date 2023-12-27
 **/
@Service("candyCommitService")
public class CandyCommitServiceImpl implements ITccService {

    @Resource
    private LuceneHelper luceneHelper;

    @Resource
    private DocumentHelper documentHelper;

    /**
     * 添加文档
     * <li>预提交为可见文档</li>
     *
     * @param entityList 列表
     */
    @Override
    public void add(List<? extends BaseEntity> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return;
        }
        // 删除所有所有比当前版本低的版本
        entityList.forEach(f -> {
            IndexBO indexBO = this.documentHelper.index(f.getClass());
            int version = f.getVersion() - 1;
            BooleanQuery.Builder builder = new BooleanQuery.Builder();
            builder.add(new TermQuery(new Term(StrConstant.D_ID, f.getId())), BooleanClause.Occur.MUST);
            builder.add(IntPoint.newRangeQuery(StrConstant.D_VERSION, Integer.MIN_VALUE, version), BooleanClause.Occur.MUST);
            this.luceneHelper.deleteDocuments(indexBO.getIndexName(), builder.build());
        });
    }

    /**
     * 更新文档
     *
     * @param entityList 列表
     */
    @Override
    public void update(List<? extends BaseEntity> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return;
        }
        IndexBO indexBO = this.documentHelper.index(entityList.get(0).getClass());
        // 移除截至上一个版本的所有版本
        BooleanQuery.Builder builder = new BooleanQuery.Builder();
        entityList.forEach(f -> {
            String id = f.getId();
            int version = f.getVersion() - 1;
            BooleanQuery.Builder delBuilder = new BooleanQuery.Builder();
            delBuilder.add(new TermQuery(new Term(StrConstant.D_ID, id)), BooleanClause.Occur.MUST);
            delBuilder.add(IntPoint.newRangeQuery(StrConstant.D_VERSION, Integer.MIN_VALUE, version), BooleanClause.Occur.MUST);
            builder.add(delBuilder.build(), BooleanClause.Occur.SHOULD);

        });
        this.luceneHelper.deleteDocuments(indexBO.getIndexName(), builder.build());
    }

    /**
     * 删除文档
     *
     * @param className 实体类名
     * @param idList    主键列表
     */
    @Override
    public void del(String className, List<String> idList) {
        if (CollUtil.isEmpty(idList)) {
            return;
        }
        // 根据id检索出文档
        BooleanQuery.Builder builder = new BooleanQuery.Builder();
        idList.forEach(f -> builder.add(new TermQuery(new Term(StrConstant.D_ID, f)), BooleanClause.Occur.SHOULD));
        Class<? extends BaseEntity> tClass = ClassUtil.loadClass(className);
        IndexBO indexBO = this.documentHelper.index(tClass);
        this.luceneHelper.deleteDocuments(indexBO.getIndexName(), builder.build());
    }
}
